use crate::physical_plan::PhysicalPlanExpr;
use crate::data_frame::{DataInstance, RealValue};
use crate::run_plan::{HandResult, HandResultFail};
use crate::lazy_static::__Deref;

pub fn set(args: &[Box<PhysicalPlanExpr>], data: &mut DataInstance) -> HandResult{
    if args.len() == 2{
        let left = &args[0];
        let right = &args[1];
        if let PhysicalPlanExpr::ElementValue(left) = left.deref(){
            match right.deref(){
                PhysicalPlanExpr::ConfValue(right) => {
                    let err_desc = format!("add args right cannot be ConfValue");
                    return HandResultFail::new(err_desc).into();
                },
                PhysicalPlanExpr::RealValue(right) => {
                    return data.set_value(left, right);
                },
                PhysicalPlanExpr::ElementValue(right) => {
                    let right = &data.get_value(right)?.value;
                    return data.set_value(left,right);
                },
                PhysicalPlanExpr::ElementListValue(_) => {
                    let err_desc = format!("add args right cannot be ElementListValue");
                    return HandResultFail::new(err_desc).into();
                },
            }
        }else{
            let err_desc = format!("add args left must be ElementValue");
            return HandResultFail::new(err_desc).into();
        }
    }else{
        let err_desc = format!("add args len must eq 2");
        return HandResultFail::new(err_desc).into();
    }
}

pub fn del(args: &[Box<PhysicalPlanExpr>], data: &mut DataInstance)->HandResult{
    for t in args.iter(){
        match t.deref(){
            PhysicalPlanExpr::ElementValue(t) => {
                data.del_key(t);
            },
            PhysicalPlanExpr::ElementListValue(t) => {
                for t in t.iter(){
                    data.del_key(t);
                }
            },
            PhysicalPlanExpr::RealValue(_) => {
                let err_desc= format!("del not support RealValue");
                return HandResultFail::new(err_desc).into();
            },
            PhysicalPlanExpr::ConfValue(_) => {
                let err_desc= format!("del not support ConfValue");
                return HandResultFail::new(err_desc).into();
            },
        }
    }

    return HandResult::new_ok(RealValue::Null);
}